//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer: sspg
// 
// Create Date: 2018/07/12 13:41:30
// Design Name: 
// Module Name: irig
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description:  
//              
//      Given a 10 MHz clock and unmodulated IRIG-B input, provides binary
// timestamp indicating the absolute time and a PPS signal.
//
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////



`timescale 1ns / 100ps
module irig(
    input                       clk_10mhz,
    input                       rst,
    input                       irigb,

    output                      irigb_invalid,
    output                      unlock,
    output                      pps,
    output      [ 5:0]          ts_second,
    output      [ 5:0]          ts_minute,
    output      [ 4:0]          ts_hour,
    output      [ 8:0]          ts_day,
    output      [ 6:0]          ts_year,
    output      [16:0]          ts_sec_day
    );
   
wire                irig_d0;
wire                irig_d1;
wire                irig_mark;
wire                pps_gate;
wire [2:0]          ts_select;
wire                ts_finish;
wire [4:0]          bit_idx;
wire [1:0]          digit_idx;
wire                bit_value;
// for jitter
reg                 irigb_d1 = 'd0;
reg                 irigb_d2 = 'd0;
reg                 irigb_d3 = 'd0;
reg                 irigb_d4 = 'd0;
wire                irigb_s;

always @(posedge clk_10mhz) begin
    irigb_d1 <= irigb;
    irigb_d2 <= irigb_d1;
    irigb_d3 <= irigb_d2;
    irigb_d4 <= irigb_d3;
end

assign      irigb_s = irigb_d1 | irigb_d2 | irigb_d3 | irigb_d4;

// Decode the IRIG-B width-encoded bits
// into data 0, data 1, and mark signals
irig_width_decode i_irig_width_decode(
                .clk(clk_10mhz),
                .rst(rst),
                .irigb(irigb_s),
                .irigb_invalid(irigb_invalid),
                .irig_mark(irig_mark),
                .irig_d0(irig_d0),
                .irig_d1(irig_d1));

// Lock onto and track the IRIG-B "states"
// separated by mark signals.  Grab the BCD and binary
// bit values and send them to the timestamp block.
irig_state i_irig_state(
                .clk(clk_10mhz),
                .rst(rst),
                .irig_d0(irig_d0),
                .irig_d1(irig_d1),
                .irig_mark(irig_mark),
                .unlock(unlock),
                .pps_gate(pps_gate),
                .ts_select(ts_select),
                .ts_finish(ts_finish),
                .bit_idx(bit_idx),
                .digit_idx(digit_idx),
                .bit_value(bit_value));

// From the BCD and binary bit values, generate
// the timestamps of the previous whole second
irig_timestamp i_irig_timestamp(
                .clk(clk_10mhz),
                .rst(rst),
                .bit_idx(bit_idx),
                .digit_idx(digit_idx),
                .bit_value(bit_value),
                .ts_select(ts_select),
                .ts_finish(ts_finish),
                .ts_second(ts_second),
                .ts_minute(ts_minute),
                .ts_hour(ts_hour),
                .ts_day(ts_day),
                .ts_year(ts_year),
                .ts_sec_day(ts_sec_day));

// PPS signal is generated by gating the IRIG signal
// during the start marker.  Technically this should be a
// negedge-registered signal, but it is directly
// generated from the change in the IRIG signal itself
// so will be set up in time. 
assign pps = irigb & pps_gate;

endmodule


